#pragma once
#include <torch/torch.h>
#include <LibDL/Tensor/Tensor.h>
#include <LibDL/utils.h>
namespace optim {

	class Optimizer {
	public:
		void zero_grad() noexcept(false) {
			core_->zero_grad();
		}
		void step() noexcept(false) {
			core_->step();
		}

		std::vector<Tensor> parameters() noexcept(false) {
			return wrap_tensor(core_->parameters());
		}
	protected:
		using TorchOptim = std::shared_ptr<torch::optim::Optimizer>;
		Optimizer(TorchOptim core)
			:core_(core) {}
		
		 std::vector<at::Tensor> map_core(const std::vector<Tensor> &v) {
			return utils::map_to_core<at::Tensor>(v);
		}
		std::vector<Tensor> wrap_tensor(const std::vector<at::Tensor>& v) {
			return utils::map_to_wrapper<Tensor>(v);
		}
		std::shared_ptr<torch::optim::Optimizer> core_;
	};


}